package supermario;

import javazoom.jl.decoder.JavaLayerException;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
//游戏2 ---超级玛丽
public class MyFrame extends JFrame implements KeyListener, Runnable {
    //用于存储所有的背景
    private List<BackGround> allBg = new ArrayList<>();
    //用于存储当前的背景
    private BackGround nowBg = new BackGround();
    //用于双缓存
    private Image offScreenImage = null;
    //马里奥对象
    private Mario mario = new Mario();
    //定义一个线程对象用于实现马里奥的运动
    private Thread thread = new Thread(this);

    public static final int START = 0;
    public static final int RUNNING = 1;
    private int state = START;

    public MyFrame() {
        //设置窗口的大小
        this.setSize(800, 600);
        //设置窗口显示居中
        this.setLocationRelativeTo(null);
        //设置窗口的可见性
        this.setVisible(true);
        //设置点击窗口关闭见关闭程序
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置成就d窗口大小不可变
        this.setResizable(false);
        //向键盘添加键盘监听器  需要实现KeyListener接口
        this.addKeyListener(this);
        //设置窗口名称
        this.setTitle("超级玛丽");
        //调用初始化图片
        StaticValue.init();
        //初始化马里奥对象
        mario = new Mario(10, 355);
        //创建全部的场景  并将第几个场景赋给BackGround的有参构造
        for (int i = 1; i <= 3; i++) {
            allBg.add(new BackGround(i, i == 3));
        }
        //将第一个场景设置为当前背景  背景从第0个开始到第三个
        nowBg = allBg.get(0);
        //将场景的setBackGround对象传递给马里奥
        mario.setBackGround(nowBg);
        //调用鼠标点击方法
        action();
        //若游戏未开始 无限 停止线程
        while (state == START) {
            Thread.yield();
        }
        //重画
        repaint();
        //启动线程
        thread.start();
        try {
            //加入音乐
            new Music();
        } catch (FileNotFoundException | JavaLayerException e) {
            e.printStackTrace();
        }

    }

    public void action() {
        //鼠标侦听器
        MouseAdapter m = new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //鼠标点击时若为游戏未开始状态则开始游戏
                if (state == START) {
                    state = RUNNING;
                }
            }
        };
        this.addMouseListener(m);
        this.addMouseMotionListener(m);
    }

    public void paint(Graphics g) {
        //窗口
        if (offScreenImage == null) {
            offScreenImage = createImage(800, 600);
        }
        //画笔
        Graphics graphics = offScreenImage.getGraphics();
        //画窗口
        graphics.fillRect(0, 0, 800, 600);
        //画背景
        graphics.drawImage(nowBg.getBgImage(), 0, 0, this);
        //画敌人
        for (Enemy o : nowBg.getEnemyList()) {
            graphics.drawImage(o.getShow(), o.getX(), o.getY(), this);
        }
        //画障碍物
        for (Obstacle ob : nowBg.getObstacleList()) {
            graphics.drawImage(ob.getShow(), ob.getX(), ob.getY(), this);
        }
        //画城堡
        graphics.drawImage(nowBg.getTower(), 620, 270, this);
        //画
        graphics.drawImage(nowBg.getGan(), 500, 220, this);
        graphics.drawImage(mario.getShow(), mario.getX(), mario.getY(), this);
        Color c = graphics.getColor();
        graphics.setColor(Color.BLACK);
        graphics.setFont(new Font("黑体", Font.BOLD, 25));
        graphics.drawString("当前分数为:" + mario.getScore(), 300, 100);
        graphics.setColor(c);
        //如果游戏未开始 画封面覆盖游戏画面
        if (state == START) {
            graphics.drawImage(BackGround.getStart(), 0, 0, this);
        }
        g.drawImage(offScreenImage, 0, 0, this);

    }

    public static void main(String[] args) {
        MyFrame myFrame = new MyFrame();
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    //当键盘按下时调用
    @Override
    public void keyPressed(KeyEvent e) {
        //向右移动
        if (e.getKeyCode() == KeyEvent.VK_D) {
            mario.rightMove();
        }
        //向左移动
        if (e.getKeyCode() == KeyEvent.VK_A) {
            mario.leftMove();
        }
        //跳跃
        if (e.getKeyCode() == KeyEvent.VK_W) {
            mario.jump();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        //向左停止
        if (e.getKeyCode() == KeyEvent.VK_A) {
            mario.leftStop();
        }
        //向右停止
        if (e.getKeyCode() == KeyEvent.VK_D) {
            mario.rightStop();
        }

    }

    @Override
    public void run() {
        while (true) {
            //调用鼠标点击方法
            action();
            //若游戏未开始 无限 停止线程
            while (state == START) {
                Thread.yield();
            }
            //如果马里奥达到了屏幕的最右  那么切换场景
            repaint();
            try {
                Thread.sleep(50);
                if (mario.getX() >= 775) {
                    nowBg = allBg.get(nowBg.getSort());
                    mario.setBackGround(nowBg);
                    mario.setX(10);
                    mario.setY(355);
                }
                //判断马里奥是否死亡
                if (mario.isDeath()) {
                    //弹窗
                    JOptionPane.showMessageDialog(this, "马里奥死亡!!");
                    System.exit(0);
                }
                //判断游戏是否结束
                if (mario.isOK()) {
                    //弹窗
                    JOptionPane.showMessageDialog(this, "恭喜你成功通关了");
                    System.exit(0);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
